package dev.http.urlconnection;

/**
 * Author:   RunAtWorld
 * Date:     2021/3/30 0:50
 */

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

/**
 * 使用 Https 的 UrlConnection
 */
@Slf4j
public class HttpsUrlConnectionUtil {

    /**
     * 发送GET请求
     *
     * @param url
     * @param headers
     * @return
     */
    public static String sendGetRequest(String url, Map headers) {
        HttpsURLConnection conn = null;
        InputStream is = null;
        OutputStream output = null;
        BufferedReader reader = null;
        BufferedWriter writer = null;

        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = {new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
                        throws CertificateException {

                }

                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
                        throws CertificateException {

                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            }};
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tm, new SecureRandom());

            conn = (HttpsURLConnection) new URL(url).openConnection();
            log.info("url:{}", conn.getURL());
            // 设置请求方式GET
            conn.setRequestMethod("GET");
            // 设置读去超时时间为10秒
            conn.setReadTimeout(10 * 1000);
            // 设置连接超时为10秒
            conn.setConnectTimeout(15 * 1000);
            // Post请求不能使用缓存
            conn.setUseCaches(false);
            // 接受输入流
            conn.setDoInput(true);
            // 启动输出流，当需要传递参数时需要开启
            conn.setDoOutput(true);
            // 添加Header
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type", "application/json");
            HttpsURLConnection finalConn = conn;
            if (headers != null) {
                headers.forEach((k, v) -> {
                    finalConn.setRequestProperty(k.toString(), v.toString());
                });
            }

            // 发起请求
            conn.connect();
            output = conn.getOutputStream();
            // 写入参数 用&分割
            // writer.write("demo=1");
            writer.flush();

            // 状态码
            int code = conn.getResponseCode();
            log.info("http code:{}", code);
            if (code == 200) {
                is = conn.getInputStream();
                reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                String line;
                StringBuffer sbf = new StringBuffer();
                while ((line = reader.readLine()) != null) {
                    sbf.append(line);
                    sbf.append("\r\n");
                }
                return sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != output) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 断开与远程地址url的连接
            conn.disconnect();
        }
        return null;
    }

    /**
     * 发送Post请求
     *
     * @param url
     * @param headers
     * @param body
     * @return
     */
    public static String sendPostRequest(String url, Map headers, Object body) {
        HttpsURLConnection conn = null;
        InputStream is = null;
        OutputStream output = null;
        BufferedReader reader = null;
        BufferedWriter writer = null;

        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = {new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
                        throws CertificateException {

                }

                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
                        throws CertificateException {

                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            }};
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tm, new SecureRandom());

            conn = (HttpsURLConnection) new URL(url).openConnection();
            log.info("url:{}", conn.getURL());
            // 设置请求方式,GET,POST
            conn.setRequestMethod("POST");
            // 设置读去超时时间为10秒
            conn.setReadTimeout(10 * 1000);
            // 设置连接超时为10秒
            conn.setConnectTimeout(15 * 1000);
            // Post请求不能使用缓存
            conn.setUseCaches(false);
            // 接受输入流
            conn.setDoInput(true);
            // 启动输出流，当需要传递参数时需要开启
            conn.setDoOutput(true);
            // 添加Header
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type", "application/json");
            HttpsURLConnection finalConn = conn;
            if (headers != null) {
                headers.forEach((k, v) -> {
                    finalConn.setRequestProperty(k.toString(), v.toString());
                });
            }

            // 添加Body
            String bodyJson = JSON.toJSONString(body);
            log.info("req body:{}", bodyJson);

            // 发起请求
            conn.connect();
            output = conn.getOutputStream();
            // 写入参数
            writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
            writer.write(bodyJson);

            // 状态码
            int code = conn.getResponseCode();
            log.info("http code:{}", code);
            if (code == 200) {
                is = conn.getInputStream();
                reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                String line;
                StringBuffer sbf = new StringBuffer();
                while ((line = reader.readLine()) != null) {
                    sbf.append(line);
                    sbf.append("\r\n");
                }
                return sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != output) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 断开与远程地址url的连接
            conn.disconnect();
        }
        return null;
    }
}